home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Resources / Developers / XAMPP 1.5.4 / Windows installer / xampp-win32-1.5.4-installer.exe / xampp / php / pear / HTML / Progress.php < prev    next >
Encoding:
PHP Script  |  2005-12-02  |  77.0 KB  |  2,239 lines

  1. <?php
  2. /**
  3.  * HTML loading bar with only PHP and JS interface.
  4.  *
  5.  * PHP versions 4 and 5
  6.  *
  7.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  8.  * that is available through the world-wide-web at the following URI:
  9.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  10.  * the PHP License and are unable to obtain it through the web, please
  11.  * send a note to license@php.net so we can mail you a copy immediately.
  12.  *
  13.  * @category   HTML
  14.  * @package    HTML_Progress
  15.  * @author     Laurent Laville <pear@laurent-laville.org>
  16.  * @copyright  1997-2005 The PHP Group
  17.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  18.  * @version    CVS: $Id: Progress.php,v 1.19 2005/10/15 11:12:23 farell Exp $
  19.  * @link       http://pear.php.net/package/HTML_Progress
  20.  * @since      File available since Release 1.0
  21.  */
  22.  
  23. require_once 'HTML/Progress/DM.php';
  24. require_once 'HTML/Progress/UI.php';
  25.  
  26. /**#@+
  27.  * Progress Bar shape types
  28.  *
  29.  * @var        integer
  30.  * @since      0.6
  31.  */
  32. define ('HTML_PROGRESS_BAR_HORIZONTAL', 1);
  33. define ('HTML_PROGRESS_BAR_VERTICAL',   2);
  34. /**#@-*/
  35.  
  36. /**#@+
  37.  * Progress Bar shape types
  38.  *
  39.  * @var        integer
  40.  * @since      1.2.0RC1
  41.  */
  42. define ('HTML_PROGRESS_POLYGONAL',      3);
  43. define ('HTML_PROGRESS_CIRCLE',         4);
  44. /**#@-*/
  45.  
  46. /**
  47.  * Basic error code that indicate a wrong input
  48.  *
  49.  * @var        integer
  50.  * @since      1.0
  51.  */
  52. define ('HTML_PROGRESS_ERROR_INVALID_INPUT',   -100);
  53.  
  54. /**
  55.  * Basic error code that indicate a wrong callback definition.
  56.  * Allows only function or class-method structure.
  57.  *
  58.  * @var        integer
  59.  * @since      1.1
  60.  */
  61. define ('HTML_PROGRESS_ERROR_INVALID_CALLBACK',-101);
  62.  
  63. /**
  64.  * Basic error code that indicate a deprecated method
  65.  * that may be removed at any time from a future version
  66.  *
  67.  * @var        integer
  68.  * @since      1.2.0RC1
  69.  */
  70. define ('HTML_PROGRESS_DEPRECATED',            -102);
  71.  
  72. /**#@+
  73.  * One of five possible return values from the error Callback
  74.  *
  75.  * @see        HTML_Progress::_handleError
  76.  * @var        integer
  77.  * @since      1.2.0
  78.  */
  79. /**
  80.  * If this is returned, then the error will be both pushed onto the stack
  81.  * and logged.
  82.  */
  83. define('HTML_PROGRESS_ERRORSTACK_PUSHANDLOG', 1);
  84. /**
  85.  * If this is returned, then the error will only be pushed onto the stack,
  86.  * and not logged.
  87.  */
  88. define('HTML_PROGRESS_ERRORSTACK_PUSH', 2);
  89. /**
  90.  * If this is returned, then the error will only be logged, but not pushed
  91.  * onto the error stack.
  92.  */
  93. define('HTML_PROGRESS_ERRORSTACK_LOG', 3);
  94. /**
  95.  * If this is returned, then the error is completely ignored.
  96.  */
  97. define('HTML_PROGRESS_ERRORSTACK_IGNORE', 4);
  98. /**
  99.  * If this is returned, then the error will only be logged, but not pushed
  100.  * onto the error stack because will halt script execution.
  101.  */
  102. define('HTML_PROGRESS_ERRORSTACK_LOGANDDIE', 5);
  103. /**#@-*/
  104.  
  105.  
  106. /**#@+
  107.  * Log types for PHP's native error_log() function
  108.  *
  109.  * @see        HTML_Progress::_errorHandler
  110.  * @var        integer
  111.  * @since      1.2.0
  112.  */
  113. /**
  114.  * Use PHP's system logger
  115.  */
  116. define('HTML_PROGRESS_LOG_TYPE_SYSTEM',  0);
  117. /**
  118.  * Use PHP's mail() function
  119.  */
  120. define('HTML_PROGRESS_LOG_TYPE_MAIL',    1);
  121. /**
  122.  * Append to a file
  123.  */
  124. define('HTML_PROGRESS_LOG_TYPE_FILE',    3);
  125. /**#@-*/
  126.  
  127. /**
  128.  * Global error message callback.
  129.  * This will be used to generate the error message
  130.  * from the error code.
  131.  *
  132.  * @global     false|string|array      $GLOBALS['_HTML_PROGRESS_CALLBACK_MESSAGE']
  133.  * @since      1.2.0
  134.  * @access     private
  135.  * @see        HTML_Progress::_initErrorHandler
  136.  */
  137. $GLOBALS['_HTML_PROGRESS_CALLBACK_MESSAGE'] = false;
  138.  
  139. /**
  140.  * Global error context callback.
  141.  * This will be used to generate the error context for an error.
  142.  *
  143.  * @global     false|string|array      $GLOBALS['_HTML_PROGRESS_CALLBACK_CONTEXT']
  144.  * @since      1.2.0
  145.  * @access     private
  146.  * @see        HTML_Progress::_initErrorHandler
  147.  */
  148. $GLOBALS['_HTML_PROGRESS_CALLBACK_CONTEXT'] = false;
  149.  
  150. /**
  151.  * Global error push callback.
  152.  * This will be called every time an error is pushed onto the stack.
  153.  * The return value will be used to determine whether to allow
  154.  * an error to be pushed or logged.
  155.  *
  156.  * @global     false|string|array      $GLOBALS['_HTML_PROGRESS_CALLBACK_PUSH']
  157.  * @since      1.2.0
  158.  * @access     private
  159.  * @see        HTML_Progress::_initErrorHandler
  160.  */
  161. $GLOBALS['_HTML_PROGRESS_CALLBACK_PUSH'] = false;
  162.  
  163. /**
  164.  * Global error handler callback.
  165.  * This will handle any errors raised by this package.
  166.  *
  167.  * @global     false|string|array      $GLOBALS['_HTML_PROGRESS_CALLBACK_ERRORHANDLER']
  168.  * @since      1.2.0
  169.  * @access     private
  170.  * @see        HTML_Progress::_initErrorHandler
  171.  */
  172. $GLOBALS['_HTML_PROGRESS_CALLBACK_ERRORHANDLER'] = false;
  173.  
  174. /**
  175.  * Global associative array of key-value pairs
  176.  * that are used to specify any handler-specific settings.
  177.  *
  178.  * @global     array                   $GLOBALS['_HTML_PROGRESS_ERRORHANDLER_OPTIONS']
  179.  * @since      1.2.0
  180.  * @access     private
  181.  * @see        HTML_Progress::_initErrorHandler
  182.  */
  183. $GLOBALS['_HTML_PROGRESS_ERRORHANDLER_OPTIONS'] = array();
  184.  
  185. /**
  186.  * Global error stack for this package.
  187.  *
  188.  * @global     array                   $GLOBALS['_HTML_PROGRESS_ERRORSTACK']
  189.  * @since      1.2.0
  190.  * @access     private
  191.  * @see        HTML_Progress::raiseError
  192.  */
  193. $GLOBALS['_HTML_PROGRESS_ERRORSTACK'] = array();
  194.  
  195.  
  196. /**
  197.  * HTML loading bar with only PHP and JS interface.
  198.  *
  199.  * The HTML_Progress class allow you to add a loading bar
  200.  * to any of your xhtml document.
  201.  * You should have a browser that accept DHTML feature.
  202.  *
  203.  * @category   HTML
  204.  * @package    HTML_Progress
  205.  * @author     Laurent Laville <pear@laurent-laville.org>
  206.  * @copyright  1997-2005 The PHP Group
  207.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  208.  * @version    Release: 1.2.5
  209.  * @link       http://pear.php.net/package/HTML_Progress
  210.  * @since      Class available since Release 1.0
  211.  */
  212.  
  213. class HTML_Progress
  214. {
  215.     /**
  216.      * Whether the progress bar is in determinate or indeterminate mode.
  217.      * The default is false.
  218.      * An indeterminate progress bar continuously displays animation indicating
  219.      * that an operation of unknown length is occuring.
  220.      *
  221.      * @var        boolean
  222.      * @since      1.0
  223.      * @access     private
  224.      * @see        setIndeterminate(), isIndeterminate()
  225.      */
  226.     var $_indeterminate;
  227.  
  228.     /**
  229.      * Whether to display a border around the progress bar.
  230.      * The default is false.
  231.      *
  232.      * @var        boolean
  233.      * @since      1.0
  234.      * @access     private
  235.      * @see        setBorderPainted(), isBorderPainted()
  236.      */
  237.     var $_paintBorder;
  238.  
  239.     /**
  240.      * Whether to textually display a string on the progress bar.
  241.      * The default is false.
  242.      * Setting this to true causes a textual display of the progress to be rendered
  243.      * on the progress bar. If the $_progressString is null, the percentage of completion
  244.      * is displayed on the progress bar. Otherwise, the $_progressString is rendered
  245.      * on the progress bar.
  246.      *
  247.      * @var        boolean
  248.      * @since      1.0
  249.      * @access     private
  250.      * @see        setStringPainted(), isStringPainted()
  251.      */
  252.     var $_paintString;
  253.  
  254.     /**
  255.      * An optional string that can be displayed on the progress bar.
  256.      * The default is null.
  257.      * Setting this to a non-null value does not imply that the string
  258.      * will be displayed.
  259.      *
  260.      * @var        string
  261.      * @since      1.0
  262.      * @access     private
  263.      * @see        getString(), setString()
  264.      */
  265.     var $_progressString;
  266.  
  267.     /**
  268.      * The data model (HTML_Progress_DM instance or extends)
  269.      * handles any mathematical issues arising from assigning faulty values.
  270.      *
  271.      * @var        object
  272.      * @since      1.0
  273.      * @access     private
  274.      * @see        getDM(), setDM()
  275.      */
  276.     var $_DM;
  277.  
  278.     /**
  279.      * The user interface (HTML_Progress_UI instance or extends)
  280.      * handles look-and-feel of the progress bar.
  281.      *
  282.      * @var        object
  283.      * @since      1.0
  284.      * @access     private
  285.      * @see        getUI(), setUI()
  286.      */
  287.     var $_UI;
  288.  
  289.     /**
  290.      * The label that uniquely identifies this progress object.
  291.      *
  292.      * @var        string
  293.      * @since      1.0
  294.      * @access     private
  295.      * @see        getIdent(), setIdent()
  296.      */
  297.     var $_ident;
  298.  
  299.     /**
  300.      * Holds all HTML_Progress_Observer objects that wish to be notified of new messages.
  301.      *
  302.      * @var        array
  303.      * @since      1.0
  304.      * @access     private
  305.      * @see        getListeners(), addListener(), removeListener()
  306.      */
  307.     var $_listeners;
  308.  
  309.     /**
  310.      * Delay in milisecond before each progress cells display.
  311.      * 1000 ms === sleep(1)
  312.      * <strong>usleep()</strong> function does not run on Windows platform.
  313.      *
  314.      * @var        integer
  315.      * @since      1.1
  316.      * @access     private
  317.      * @see        setAnimSpeed()
  318.      */
  319.     var $_anim_speed;
  320.  
  321.     /**
  322.      * Callback, either function name or array(&$object, 'method')
  323.      *
  324.      * @var        mixed
  325.      * @since      1.2.0RC3
  326.      * @access     private
  327.      * @see        setProgressHandler()
  328.      */
  329.     var $_callback = null;
  330.  
  331.  
  332.     /**
  333.      * Constructor Summary
  334.      *
  335.      * o Creates a natural horizontal progress bar that displays ten cells/units
  336.      *   with no border and no progress string.
  337.      *   The initial and minimum values are 0, and the maximum is 100.
  338.      *   <code>
  339.      *   $bar = new HTML_Progress();
  340.      *   </code>
  341.      *
  342.      * o Creates a natural progress bar with the specified orientation, which can be
  343.      *   either HTML_PROGRESS_BAR_HORIZONTAL or HTML_PROGRESS_BAR_VERTICAL
  344.      *   By default, no border and no progress string are painted.
  345.      *   The initial and minimum values are 0, and the maximum is 100.
  346.      *   <code>
  347.      *   $bar = new HTML_Progress($orient);
  348.      *   </code>
  349.      *
  350.      * o Creates a natural horizontal progress bar with the specified minimum and
  351.      *   maximum. Sets the initial value of the progress bar to the specified
  352.      *   minimum, and the maximum that the progress bar can reach.
  353.      *   By default, no border and no progress string are painted.
  354.      *   <code>
  355.      *   $bar = new HTML_Progress($min, $max);
  356.      *   </code>
  357.      *
  358.      * o Creates a natural horizontal progress bar with the specified orientation,
  359.      *   minimum and maximum. Sets the initial value of the progress bar to the
  360.      *   specified minimum, and the maximum that the progress bar can reach.
  361.      *   By default, no border and no progress string are painted.
  362.      *   <code>
  363.      *   $bar = new HTML_Progress($orient, $min, $max);
  364.      *   </code>
  365.      *
  366.      * o Creates a natural horizontal progress that uses the specified model
  367.      *   to hold the progress bar's data.
  368.      *   By default, no border and no progress string are painted.
  369.      *   <code>
  370.      *   $bar = new HTML_Progress($model);
  371.      *   </code>
  372.      *
  373.      *
  374.      * @param      object    $model         (optional) Model that hold the progress bar's data
  375.      * @param      int       $orient        (optional) Orientation of progress bar
  376.      * @param      int       $min           (optional) Minimum value of progress bar
  377.      * @param      int       $max           (optional) Maximum value of progress bar
  378.      * @param      array     $errorPrefs    (optional) Always last argument of class constructor.
  379.      *                                       hash of params to configure PEAR_ErrorStack and loggers
  380.      *
  381.      * @since      1.0
  382.      * @access     public
  383.      * @throws     HTML_PROGRESS_ERROR_INVALID_INPUT
  384.      * @see        setIndeterminate(),
  385.      *             setBorderPainted(), setStringPainted(), setString(),
  386.      *             setDM(), setUI(), setIdent()
  387.      */
  388.     function HTML_Progress()
  389.     {
  390.         $args = func_get_args();
  391.         $num_args = func_num_args();
  392.  
  393.         if ($num_args > 0) {
  394.             $errorPrefs = func_get_arg($num_args - 1);
  395.             if (!is_array($errorPrefs)) {
  396.                 $errorPrefs = array();
  397.             } else {
  398.                 $num_args--;
  399.             }
  400.             HTML_Progress::_initErrorHandler($errorPrefs);
  401.         } else {
  402.             HTML_Progress::_initErrorhandler();
  403.         }
  404.  
  405.         $this->_listeners = array();          // none listeners by default
  406.  
  407.         $this->_DM = new HTML_Progress_DM();  // new instance of a progress DataModel
  408.         $this->_UI = new HTML_Progress_UI();  // new instance of a progress UserInterface
  409.  
  410.         switch ($num_args) {
  411.          case 1:
  412.             if (is_object($args[0]) && (is_a($args[0], 'html_progress_dm'))) {
  413.                 /*   object html_progress_dm extends   */
  414.                 $this->_DM = &$args[0];
  415.  
  416.             } elseif (is_int($args[0])) {
  417.                 /*   int orient   */
  418.                 $this->_UI->setOrientation($args[0]);
  419.  
  420.             } else {
  421.                 return HTML_Progress::raiseError(HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  422.                     array('var' => '$model | $orient',
  423.                           'was' => (gettype($args[0]) == 'object') ?
  424.                                     get_class($args[0]).' object' : gettype($args[0]),
  425.                           'expected' => 'html_progress_dm object | integer',
  426.                           'paramnum' => 1));
  427.             }
  428.             break;
  429.          case 2:
  430.             /*   int min, int max   */
  431.             if (!is_int($args[0])) {
  432.                 return HTML_Progress::raiseError(HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  433.                     array('var' => '$min',
  434.                           'was' => $args[0],
  435.                           'expected' => 'integer',
  436.                           'paramnum' => 1));
  437.  
  438.             } elseif (!is_int($args[1])) {
  439.                 return HTML_Progress::raiseError(HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  440.                     array('var' => '$max',
  441.                           'was' => $args[1],
  442.                           'expected' => 'integer',
  443.                           'paramnum' => 2));
  444.             } else {
  445.                 $this->_DM->setMinimum($args[0]);
  446.                 $this->_DM->setMaximum($args[1]);
  447.             }
  448.             break;
  449.          case 3:
  450.             /*   int orient, int min, int max   */
  451.             if (!is_int($args[0])) {
  452.                 return HTML_Progress::raiseError(HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  453.                     array('var' => '$orient',
  454.                           'was' => $args[0],
  455.                           'expected' => 'integer',
  456.                           'paramnum' => 1));
  457.  
  458.             } elseif (!is_int($args[1])) {
  459.                 return HTML_Progress::raiseError(HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  460.                     array('var' => '$min',
  461.                           'was' => $args[1],
  462.                           'expected' => 'integer',
  463.                           'paramnum' => 2));
  464.  
  465.             } elseif (!is_int($args[2])) {
  466.                 return HTML_Progress::raiseError(HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  467.                     array('var' => '$max',
  468.                           'was' => $args[2],
  469.                           'expected' => 'integer',
  470.                           'paramnum' => 3));
  471.             } else {
  472.                 $this->_UI->setOrientation($args[0]);
  473.                 $this->_DM->setMinimum($args[1]);
  474.                 $this->_DM->setMaximum($args[2]);
  475.             }
  476.             break;
  477.          default:
  478.         }
  479.         $this->setString(null);
  480.         $this->setStringPainted(false);
  481.         $this->setBorderPainted(false);
  482.         $this->setIndeterminate(false);
  483.         $this->setIdent();
  484.         $this->setAnimSpeed(0);
  485.  
  486.         // to fix a potential php config problem with PHP 4.2.0 : turn 'implicit_flush' ON
  487.         ob_implicit_flush(1);
  488.     }
  489.  
  490.     /**
  491.      * Returns the current API version
  492.      *
  493.      * @return     float
  494.      * @since      0.1
  495.      * @access     public
  496.      */
  497.     function apiVersion()
  498.     {
  499.         return 1.2;
  500.     }
  501.  
  502.     /**
  503.      * Returns mode of the progress bar (determinate or not).
  504.      *
  505.      * @return     boolean
  506.      * @since      1.0
  507.      * @access     public
  508.      * @see        setIndeterminate()
  509.      */
  510.     function isIndeterminate()
  511.     {
  512.         return $this->_indeterminate;
  513.     }
  514.  
  515.     /**
  516.      * Sets the $_indeterminate property of the progress bar, which determines
  517.      * whether the progress bar is in determinate or indeterminate mode.
  518.      * An indeterminate progress bar continuously displays animation indicating
  519.      * that an operation of unknown length is occuring.
  520.      * By default, this property is false.
  521.      *
  522.      * @param      boolean   $continuous    whether countinuously displays animation
  523.      *
  524.      * @return     void
  525.      * @since      1.0
  526.      * @access     public
  527.      * @throws     HTML_PROGRESS_ERROR_INVALID_INPUT
  528.      * @see        isIndeterminate()
  529.      */
  530.     function setIndeterminate($continuous)
  531.     {
  532.         if (!is_bool($continuous)) {
  533.             return HTML_Progress::raiseError(HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  534.                 array('var' => '$continuous',
  535.                       'was' => gettype($continuous),
  536.                       'expected' => 'boolean',
  537.                       'paramnum' => 1));
  538.         }
  539.         $this->_indeterminate = $continuous;
  540.     }
  541.  
  542.     /**
  543.      * Determines whether the progress bar border is painted or not.
  544.      * The default is false.
  545.      *
  546.      * @return     boolean
  547.      * @since      1.0
  548.      * @access     public
  549.      * @see        setBorderPainted()
  550.      */
  551.     function isBorderPainted()
  552.     {
  553.         return $this->_paintBorder;
  554.     }
  555.  
  556.     /**
  557.      * Sets the value of $_paintBorder property, which determines whether the
  558.      * progress bar should paint its border. The default is false.
  559.      *
  560.      * @param      boolean   $paint         whether the progress bar should paint its border
  561.      *
  562.      * @return     void
  563.      * @since      1.0
  564.      * @access     public
  565.      * @throws     HTML_PROGRESS_ERROR_INVALID_INPUT
  566.      * @see        isBorderPainted()
  567.      */
  568.     function setBorderPainted($paint)
  569.     {
  570.         if (!is_bool($paint)) {
  571.             return HTML_Progress::raiseError(HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  572.                 array('var' => '$paint',
  573.                       'was' => gettype($paint),
  574.                       'expected' => 'boolean',
  575.                       'paramnum' => 1));
  576.         }
  577.  
  578.         $this->_paintBorder = $paint;
  579.     }
  580.  
  581.     /**
  582.      * Determines whether the progress bar string is painted or not.
  583.      * The default is false.
  584.      * The progress bar displays the value returned by getPercentComplete() method
  585.      * formatted as a percent such as 33%.
  586.      *
  587.      * @return     boolean
  588.      * @since      1.0
  589.      * @access     public
  590.      * @see        setStringPainted(), setString()
  591.      */
  592.     function isStringPainted()
  593.     {
  594.         return $this->_paintString;
  595.     }
  596.  
  597.     /**
  598.      * Sets the value of $_paintString property, which determines whether the
  599.      * progress bar should render a progress string. The default is false.
  600.      *
  601.      * @param      boolean   $paint         whether the progress bar should render a string
  602.      *
  603.      * @return     void
  604.      * @since      1.0
  605.      * @access     public
  606.      * @throws     HTML_PROGRESS_ERROR_INVALID_INPUT
  607.      * @see        isStringPainted(), setString()
  608.      */
  609.     function setStringPainted($paint)
  610.     {
  611.         if (!is_bool($paint)) {
  612.             return HTML_Progress::raiseError(HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  613.                 array('var' => '$paint',
  614.                       'was' => gettype($paint),
  615.                       'expected' => 'boolean',
  616.                       'paramnum' => 1));
  617.         }
  618.         $this->_paintString = $paint;
  619.     }
  620.  
  621.     /**
  622.      * Returns the current value of the progress string.
  623.      * By default, the progress bar displays the value returned by
  624.      * getPercentComplete() method formatted as a percent such as 33%.
  625.      *
  626.      * @return     string
  627.      * @since      1.0
  628.      * @access     public
  629.      * @see        setString(), isStringPainted()
  630.      */
  631.     function getString()
  632.     {
  633.         if ($this->isStringPainted() && !is_null($this->_progressString)) {
  634.             return $this->_progressString;
  635.         } else {
  636.             return sprintf("%s", $this->getPercentComplete(false)).' %';
  637.         }
  638.     }
  639.  
  640.     /**
  641.      * Sets the current value of the progress string. By default, this string
  642.      * is null. If you have provided a custom progress string and want to revert
  643.      * to the built-in-behavior, set the string back to null.
  644.      * The progress string is painted only if the isStringPainted() method
  645.      * returns true.
  646.      *
  647.      * @param      string    $str           progress string
  648.      *
  649.      * @return     void
  650.      * @since      1.0
  651.      * @access     public
  652.      * @see        getString(), isStringPainted(), setStringPainted()
  653.      */
  654.     function setString($str)
  655.     {
  656.         $this->_progressString = $str;
  657.     }
  658.  
  659.     /**
  660.      * Returns the data model used by this progress bar.
  661.      *
  662.      * @return     object
  663.      * @since      1.0
  664.      * @access     public
  665.      * @see        setDM()
  666.      */
  667.     function &getDM()
  668.     {
  669.         return $this->_DM;
  670.     }
  671.  
  672.     /**
  673.      * Sets the data model used by this progress bar.
  674.      *
  675.      * @param      string    $model         class name of a html_progress_dm extends object
  676.      *
  677.      * @return     void
  678.      * @since      1.0
  679.      * @access     public
  680.      * @throws     HTML_PROGRESS_ERROR_INVALID_INPUT
  681.      * @see        getDM()
  682.      */
  683.     function setDM($model)
  684.     {
  685.         if (!class_exists($model)) {
  686.             return HTML_Progress::raiseError(HTML_PROGRESS_ERROR_INVALID_INPUT, 'error',
  687.                 array('var' => '$model',
  688.                       'was' => 'class does not exists',
  689.                       'expected' => $model.' class defined',
  690.                       'paramnum' => 1));
  691.         }
  692.  
  693.         $_dm = new $model();
  694.  
  695.         if (!is_a($_dm, 'html_progress_dm')) {
  696.             return HTML_Progress::raiseError(HTML_PROGRESS_ERROR_INVALID_INPUT, 'error',
  697.                 array('var' => '$model',
  698.                       'was' => $model,
  699.                       'expected' => 'HTML_Progress_DM extends',
  700.                       'paramnum' => 1));
  701.         }
  702.         $this->_DM =& $_dm;
  703.     }
  704.  
  705.     /**
  706.      * Returns the progress bar's minimum value stored in the progress bar's data model.
  707.      * The default value is 0.
  708.      *
  709.      * @return     integer
  710.      * @since      1.0
  711.      * @access     public
  712.      * @see        setMinimum(),
  713.      *             HTML_Progress_DM::getMinimum()
  714.      */
  715.     function getMinimum()
  716.     {
  717.         return $this->_DM->getMinimum();
  718.     }
  719.  
  720.     /**
  721.      * Sets the progress bar's minimum value stored in the progress bar's data model.
  722.      * If the minimum value is different from previous minimum, all change listeners
  723.      * are notified.
  724.      *
  725.      * @param      integer   $min           progress bar's minimal value
  726.      *
  727.      * @return     void
  728.      * @since      1.0
  729.      * @access     public
  730.      * @see        getMinimum(),
  731.      *             HTML_Progress_DM::setMinimum()
  732.      */
  733.     function setMinimum($min)
  734.     {
  735.         $oldVal = $this->getMinimum();
  736.  
  737.         $this->_DM->setMinimum($min);
  738.  
  739.         if ($oldVal != $min) {
  740.             $this->_announce(array('log' => 'setMinimum', 'value' => $min));
  741.         }
  742.     }
  743.  
  744.     /**
  745.      * Returns the progress bar's maximum value stored in the progress bar's data model.
  746.      * The default value is 100.
  747.      *
  748.      * @return     integer
  749.      * @since      1.0
  750.      * @access     public
  751.      * @see        setMaximum(),
  752.      *             HTML_Progress_DM::getMaximum()
  753.      */
  754.     function getMaximum()
  755.     {
  756.         return $this->_DM->getMaximum();
  757.     }
  758.  
  759.     /**
  760.      * Sets the progress bar's maximum value stored in the progress bar's data model.
  761.      * If the maximum value is different from previous maximum, all change listeners
  762.      * are notified.
  763.      *
  764.      * @param      integer   $max           progress bar's maximal value
  765.      *
  766.      * @return     void
  767.      * @since      1.0
  768.      * @access     public
  769.      * @see        getMaximum(),
  770.      *             HTML_Progress_DM::setMaximum()
  771.      */
  772.     function setMaximum($max)
  773.     {
  774.         $oldVal = $this->getMaximum();
  775.  
  776.         $this->_DM->setMaximum($max);
  777.  
  778.         if ($oldVal != $max) {
  779.             $this->_announce(array('log' => 'setMaximum', 'value' => $max));
  780.         }
  781.     }
  782.  
  783.     /**
  784.      * Returns the progress bar's increment value stored in the progress bar's data model.
  785.      * The default value is +1.
  786.      *
  787.      * @return     integer
  788.      * @since      1.0
  789.      * @access     public
  790.      * @see        setIncrement(),
  791.      *             HTML_Progress_DM::getIncrement()
  792.      */
  793.     function getIncrement()
  794.     {
  795.         return $this->_DM->getIncrement();
  796.     }
  797.  
  798.     /**
  799.      * Sets the progress bar's increment value stored in the progress bar's data model.
  800.      *
  801.      * @param      integer   $inc           progress bar's increment value
  802.      *
  803.      * @return     void
  804.      * @since      1.0
  805.      * @access     public
  806.      * @see        getIncrement(),
  807.      *             HTML_Progress_DM::setIncrement()
  808.      */
  809.     function setIncrement($inc)
  810.     {
  811.         $this->_DM->setIncrement($inc);
  812.     }
  813.  
  814.     /**
  815.      * Returns the progress bar's current value, which is stored in the
  816.      * progress bar's data model. The value is always between the minimum
  817.      * and maximum values, inclusive.
  818.      * By default, the value is initialized to be equal to the minimum value.
  819.      *
  820.      * @return     integer
  821.      * @since      1.0
  822.      * @access     public
  823.      * @see        setValue(), incValue(),
  824.      *             HTML_Progress_DM::getValue()
  825.      */
  826.     function getValue()
  827.     {
  828.         return $this->_DM->getValue();
  829.     }
  830.  
  831.     /**
  832.      * Sets the progress bar's current value stored in the progress bar's data model.
  833.      * If the new value is different from previous value, all change listeners
  834.      * are notified.
  835.      *
  836.      * @param      integer   $val           progress bar's current value
  837.      *
  838.      * @return     void
  839.      * @since      1.0
  840.      * @access     public
  841.      * @see        getValue(), incValue(),
  842.      *             HTML_Progress_DM::setValue()
  843.      */
  844.     function setValue($val)
  845.     {
  846.         $oldVal = $this->getValue();
  847.  
  848.         $this->_DM->setValue($val);
  849.  
  850.         if ($oldVal != $val) {
  851.             $this->_announce(array('log' => 'setValue', 'value' => $val));
  852.         }
  853.     }
  854.  
  855.     /**
  856.      * Updates the progress bar's current value by adding increment value.
  857.      * All change listeners are notified.
  858.      *
  859.      * @return     void
  860.      * @since      1.0
  861.      * @access     public
  862.      * @see        getValue(), setValue(),
  863.      *             HTML_Progress_DM::incValue()
  864.      */
  865.     function incValue()
  866.     {
  867.         $this->_DM->incValue();
  868.         $this->_announce(array('log' => 'incValue', 'value' => $this->_DM->getValue() ));
  869.     }
  870.  
  871.     /**
  872.      * Returns the percent complete for the progress bar. Note that this number is
  873.      * between 0.00 and 1.00 or 0 and 100.
  874.      *
  875.      * @param      boolean   $float         (optional) float or integer format
  876.      *
  877.      * @return     mixed
  878.      * @since      1.0
  879.      * @access     public
  880.      * @see        getValue(), getMaximum(),
  881.      *             HTML_Progress_DM::getPercentComplete()
  882.      */
  883.     function getPercentComplete($float = true)
  884.     {
  885.         return $this->_DM->getPercentComplete($float);
  886.     }
  887.  
  888.     /**
  889.      * Returns the look-and-feel object that renders the progress bar.
  890.      *
  891.      * @return     object
  892.      * @since      1.0
  893.      * @access     public
  894.      * @see        setUI()
  895.      */
  896.     function &getUI()
  897.     {
  898.         return $this->_UI;
  899.     }
  900.  
  901.     /**
  902.      * Sets the look-and-feel object that renders the progress bar.
  903.      *
  904.      * @param      string    $ui            class name of a html_progress_ui extends object
  905.      *
  906.      * @return     void
  907.      * @since      1.0
  908.      * @access     public
  909.      * @throws     HTML_PROGRESS_ERROR_INVALID_INPUT
  910.      * @see        getUI()
  911.      */
  912.     function setUI($ui)
  913.     {
  914.         if (!class_exists($ui)) {
  915.             return HTML_Progress::raiseError(HTML_PROGRESS_ERROR_INVALID_INPUT, 'error',
  916.                 array('var' => '$ui',
  917.                       'was' => 'class does not exists',
  918.                       'expected' => $ui.' class defined',
  919.                       'paramnum' => 1));
  920.         }
  921.  
  922.         $_ui = new $ui();
  923.  
  924.         if (!is_a($_ui, 'html_progress_ui')) {
  925.             return HTML_Progress::raiseError(HTML_PROGRESS_ERROR_INVALID_INPUT, 'error',
  926.                 array('var' => '$ui',
  927.                       'was' => $ui,
  928.                       'expected' => 'HTML_Progress_UI extends',
  929.                       'paramnum' => 1));
  930.         }
  931.         $this->_UI =& $_ui;
  932.     }
  933.  
  934.     /**
  935.      * Sets the look-and-feel model that renders the progress bar.
  936.      *
  937.      * @param      string    $file          file name of model properties
  938.      * @param      string    $type          type of external ressource (phpArray, iniFile, XML ...)
  939.      *
  940.      * @return     void
  941.      * @since      1.0
  942.      * @access     public
  943.      * @throws     HTML_PROGRESS_ERROR_INVALID_INPUT
  944.      * @see        setUI()
  945.      */
  946.     function setModel($file, $type)
  947.     {
  948.         if (!file_exists($file)) {
  949.             return HTML_Progress::raiseError(HTML_PROGRESS_ERROR_INVALID_INPUT, 'error',
  950.                 array('var' => '$file',
  951.                       'was' => $file,
  952.                       'expected' => 'file exists',
  953.                       'paramnum' => 1));
  954.         }
  955.  
  956.         include_once 'Config.php';
  957.  
  958.         $conf = new Config();
  959.  
  960.         if (!$conf->isConfigTypeRegistered($type)) {
  961.             return HTML_Progress::raiseError(HTML_PROGRESS_ERROR_INVALID_INPUT, 'error',
  962.                 array('var' => '$type',
  963.                       'was' => $type,
  964.                       'expected' => implode (" | ", array_keys($GLOBALS['CONFIG_TYPES'])),
  965.                       'paramnum' => 2));
  966.         }
  967.  
  968.         $data = $conf->parseConfig($file, $type);
  969.  
  970.         $structure = $data->toArray(false);
  971.         $progress =& $structure['root'];
  972.  
  973.         $ui = new HTML_Progress_UI();
  974.  
  975.         if (isset($progress['core']['speed'])) {
  976.             $this->setAnimSpeed(intval($progress['core']['speed']));
  977.         }
  978.  
  979.         if (isset($progress['core']['indeterminate'])) {
  980.             $mode = (strtolower(trim($progress['core']['indeterminate'])) == 'true');
  981.             $this->setIndeterminate($mode);
  982.         }
  983.  
  984.         if (isset($progress['core']['increment'])) {
  985.             $this->setIncrement(intval($progress['core']['increment']));
  986.         }
  987.  
  988.         if (isset($progress['core']['javascript']) && file_exists($progress['core']['javascript'])) {
  989.             $ui->setScript($progress['core']['javascript']);
  990.         }
  991.  
  992.         if (isset($progress['orientation']['shape'])) {
  993.             $ui->setOrientation(intval($progress['orientation']['shape']));
  994.         }
  995.  
  996.         if (isset($progress['orientation']['fillway'])) {
  997.             $ui->setFillWay($progress['orientation']['fillway']);
  998.         }
  999.  
  1000.         if (isset($progress['cell']['count'])) {
  1001.             $ui->setCellCount(intval($progress['cell']['count']));
  1002.         }
  1003.  
  1004.         if (isset($progress['cell']['font-family'])) {
  1005.             if (is_array($progress['cell']['font-family'])) {
  1006.                 $progress['cell']['font-family'] = implode(",", $progress['cell']['font-family']);
  1007.             }
  1008.         }
  1009.         if (isset($progress['cell'])) {
  1010.             $ui->setCellAttributes($progress['cell']);
  1011.         }
  1012.  
  1013.         if (isset($progress['border'])) {
  1014.             $this->setBorderPainted(true);
  1015.             $ui->setBorderAttributes($progress['border']);
  1016.         }
  1017.  
  1018.         if (isset($progress['string']['font-family'])) {
  1019.             if (is_array($progress['string']['font-family'])) {
  1020.                 $progress['string']['font-family'] = implode(",", $progress['string']['font-family']);
  1021.             }
  1022.         }
  1023.         if (isset($progress['string'])) {
  1024.             $this->setStringPainted(true);
  1025.             $ui->setStringAttributes($progress['string']);
  1026.         }
  1027.  
  1028.         if (isset($progress['progress'])) {
  1029.             $ui->setProgressAttributes($progress['progress']);
  1030.         }
  1031.  
  1032.         $this->_UI = $ui;
  1033.     }
  1034.  
  1035.     /**
  1036.      * Returns delay execution of the progress bar
  1037.      *
  1038.      * @return     integer
  1039.      * @since      1.2.0RC1
  1040.      * @access     public
  1041.      * @see        setAnimSpeed()
  1042.      */
  1043.     function getAnimSpeed()
  1044.     {
  1045.         return $this->_anim_speed;
  1046.     }
  1047.  
  1048.     /**
  1049.      * Set the delays progress bar execution for the given number of miliseconds.
  1050.      *
  1051.      * @param      integer   $delay         Delay in milisecond.
  1052.      *
  1053.      * @return     void
  1054.      * @since      1.1
  1055.      * @access     public
  1056.      * @throws     HTML_PROGRESS_ERROR_INVALID_INPUT
  1057.      * @see        getAnimSpeed()
  1058.      */
  1059.     function setAnimSpeed($delay)
  1060.     {
  1061.         if (!is_int($delay)) {
  1062.             return HTML_Progress::raiseError(HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  1063.                 array('var' => '$delay',
  1064.                       'was' => gettype($delay),
  1065.                       'expected' => 'integer',
  1066.                       'paramnum' => 1));
  1067.  
  1068.         } elseif ($delay < 0) {
  1069.             return HTML_Progress::raiseError(HTML_PROGRESS_ERROR_INVALID_INPUT, 'error',
  1070.                 array('var' => '$delay',
  1071.                       'was' => $delay,
  1072.                       'expected' => 'greater than zero',
  1073.                       'paramnum' => 1));
  1074.  
  1075.         } elseif ($delay > 1000) {
  1076.             return HTML_Progress::raiseError(HTML_PROGRESS_ERROR_INVALID_INPUT, 'error',
  1077.                 array('var' => '$delay',
  1078.                       'was' => $delay,
  1079.                       'expected' => 'less or equal 1000',
  1080.                       'paramnum' => 1));
  1081.         }
  1082.         $this->_anim_speed = $delay;
  1083.     }
  1084.  
  1085.     /**
  1086.      * Get the cascading style sheet to put inline on HTML document
  1087.      *
  1088.      * @return     string
  1089.      * @since      1.0
  1090.      * @access     public
  1091.      * @see        HTML_Progress_UI::getStyle()
  1092.      */
  1093.     function getStyle()
  1094.     {
  1095.         $ui = $this->getUI();
  1096.         $lnEnd = $ui->_getLineEnd();
  1097.  
  1098.         $style = $lnEnd . $ui->getStyle();
  1099.         $style = str_replace('{%pIdent%}', '.'.$this->getIdent(), $style);
  1100.  
  1101.         if (!$this->isBorderPainted()) {
  1102.             $style = ereg_replace('border-width: [0-9]+px;', 'border-width: 0;', $style);
  1103.         }
  1104.         return $style;
  1105.     }
  1106.  
  1107.     /**
  1108.      * Get the javascript code to manage progress bar.
  1109.      *
  1110.      * @return     string                   JavaScript URL or inline code to manage progress bar
  1111.      * @since      1.0
  1112.      * @access     public
  1113.      * @see        HTML_Progress_UI::getScript()
  1114.      */
  1115.     function getScript()
  1116.     {
  1117.         $ui = $this->getUI();
  1118.         $js = $ui->getScript();
  1119.         return $js;
  1120.     }
  1121.  
  1122.     /**
  1123.      * Returns the progress bar structure in an array.
  1124.      *
  1125.      * @return     array of progress bar properties
  1126.      * @since      1.0
  1127.      * @access     public
  1128.      */
  1129.     function toArray()
  1130.     {
  1131.         $ui =& $this->getUI();
  1132.         $dm =& $this->getDM();
  1133.  
  1134.         $_structure = array();
  1135.         $_structure['id'] = $this->getIdent();
  1136.         $_structure['indeterminate'] = $this->isIndeterminate();
  1137.         $_structure['borderpainted'] = $this->isBorderPainted();
  1138.         $_structure['stringpainted'] = $this->isStringPainted();
  1139.         $_structure['string'] = $this->_progressString;
  1140.         $_structure['animspeed'] = $this->getAnimSpeed();
  1141.         $_structure['ui']['classID'] = get_class($ui);
  1142.         $_structure['ui']['orientation'] = $ui->getOrientation();
  1143.         $_structure['ui']['fillway'] = $ui->getFillWay();
  1144.         $_structure['ui']['cell'] = $ui->getCellAttributes();
  1145.         $_structure['ui']['cell']['count'] = $ui->getCellCount();
  1146.         $_structure['ui']['border'] = $ui->getBorderAttributes();
  1147.         $_structure['ui']['string'] = $ui->getStringAttributes();
  1148.         $_structure['ui']['progress'] = $ui->getProgressAttributes();
  1149.         $_structure['ui']['script'] = $ui->getScript();
  1150.         $_structure['dm']['classID'] = get_class($dm);
  1151.         $_structure['dm']['minimum'] = $dm->getMinimum();
  1152.         $_structure['dm']['maximum'] = $dm->getMaximum();
  1153.         $_structure['dm']['increment'] = $dm->getIncrement();
  1154.         $_structure['dm']['value'] = $dm->getValue();
  1155.         $_structure['dm']['percent'] = $dm->getPercentComplete(false);
  1156.  
  1157.         return $_structure;
  1158.     }
  1159.  
  1160.     /**
  1161.      * Returns the progress structure as HTML.
  1162.      *
  1163.      * @return     string                   HTML Progress bar
  1164.      * @since      0.2
  1165.      * @access     public
  1166.      */
  1167.     function toHtml()
  1168.     {
  1169.         $strHtml = '';
  1170.         $ui =& $this->_UI;
  1171.         $tabs = $ui->_getTabs();
  1172.         $tab = $ui->_getTab();
  1173.         $lnEnd = $ui->_getLineEnd();
  1174.         $comment = $ui->getComment();
  1175.         $orient = $ui->getOrientation();
  1176.         $progressAttr = $ui->getProgressAttributes();
  1177.         $borderAttr = $ui->getBorderAttributes();
  1178.         $stringAttr = $ui->getStringAttributes();
  1179.         $valign = strtolower($stringAttr['valign']);
  1180.  
  1181.         /**
  1182.          *  Adds a progress bar legend in html code is possible.
  1183.          *  See HTML_Common::setComment() method.
  1184.          */
  1185.         if (strlen($comment) > 0) {
  1186.             $strHtml .= $tabs . "<!-- $comment -->" . $lnEnd;
  1187.         }
  1188.  
  1189.         $strHtml .= $tabs . "<div id=\"".$this->getIdent()."_progress\" class=\"".$this->getIdent()."\">" . $lnEnd;
  1190.         $strHtml .= $tabs . "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">" . $lnEnd;
  1191.         $progressId = $this->getIdent().'_';
  1192.  
  1193.         /**
  1194.          *  Creates all cells of progress bar in order
  1195.          *  depending of the FillWay and Orientation.
  1196.          */
  1197.         if ($orient == HTML_PROGRESS_BAR_HORIZONTAL) {
  1198.             $progressHtml = $this->_getProgressHbar_toHtml();
  1199.         }
  1200.  
  1201.         if ($orient == HTML_PROGRESS_BAR_VERTICAL) {
  1202.             $progressHtml = $this->_getProgressVbar_toHtml();
  1203.         }
  1204.  
  1205.         if ($orient == HTML_PROGRESS_POLYGONAL) {
  1206.             $progressHtml = $this->_getProgressPolygonal_toHtml();
  1207.         }
  1208.  
  1209.         if ($orient == HTML_PROGRESS_CIRCLE) {
  1210.             $cellAttr = $ui->getCellAttributes();
  1211.             if (!isset($cellAttr[0]['background-image']) || !file_exists($cellAttr[0]['background-image'])) {
  1212.                 // creates default circle segments pictures :
  1213.                 // 'c0.png'->0% 'c1.png'->10%, 'c2.png'->20%, ... 'c10.png'->100%
  1214.                 $ui->drawCircleSegments();
  1215.             }
  1216.             $progressHtml = $this->_getProgressCircle_toHtml();
  1217.         }
  1218.  
  1219.         /**
  1220.          *  Progress Bar (2) alignment rules:
  1221.          *  - percent / messsage area (1)
  1222.          *
  1223.          *  +---------------------------------------+
  1224.          *  |         +t1---+                       |
  1225.          *  |         | (1) |                       |
  1226.          *  |         +-----+                       |
  1227.          *  | +t2---+ +-------------------+ +t3---+ |
  1228.          *  | | (1) | | | | | (2) | | | | | | (1) | |
  1229.          *  | +-----+ +-------------------+ +-----+ |
  1230.          *  |         +t4---+                       |
  1231.          *  |         | (1) |                       |
  1232.          *  |         +-----+                       |
  1233.          *  +---------------------------------------+
  1234.          */
  1235.         if (($valign == 'left') || ($valign == 'right')) {
  1236.             $tRows = 1;
  1237.             $tCols = 2;
  1238.             $ps = ($valign == 'left') ? 0 : 1;
  1239.         } else {
  1240.             $tRows = 2;
  1241.             $tCols = 1;
  1242.             $ps = ($valign == 'top')  ? 0 : 1;
  1243.         }
  1244.  
  1245.         for ($r = 0 ; $r < $tRows ; $r++) {
  1246.             $strHtml .= $tabs . "<tr>" . $lnEnd;
  1247.             for ($c = 0 ; $c < $tCols ; $c++) {
  1248.                 if (($c == $ps) || ($r == $ps)) {
  1249.                     $id = $stringAttr['id'];
  1250.                     $strHtml .= $tabs . $tab . "<td class=\"$id\" id=\"$progressId$id\">" . $lnEnd;
  1251.                     $strHtml .= $tabs . $tab . $tab . $this->getString() . $lnEnd;
  1252.                     $ps = -1;
  1253.                 } else {
  1254.                     $class = $progressAttr['class'];
  1255.                     $strHtml .= $tabs . $tab ."<td class=\"$class\">" . $lnEnd;
  1256.                     $strHtml .= $tabs . $tab . $tab . "<div class=\"".$borderAttr['class']."\">" . $lnEnd;
  1257.                     $strHtml .= $progressHtml;
  1258.                     $strHtml .= $tabs . $tab . $tab . "</div>" . $lnEnd;
  1259.                 }
  1260.                 $strHtml .= $tabs . $tab ."</td>" . $lnEnd;
  1261.             }
  1262.             $strHtml .= $tabs . "</tr>" . $lnEnd;
  1263.         }
  1264.  
  1265.         $strHtml .= $tabs . "</table>" . $lnEnd;
  1266.         $strHtml .= $tabs . "</div>" . $lnEnd;
  1267.  
  1268.         return $strHtml;
  1269.     }
  1270.  
  1271.     /**
  1272.      * Renders the new value of progress bar.
  1273.      *
  1274.      * @return     void
  1275.      * @since      0.2
  1276.      * @access     public
  1277.      */
  1278.     function display()
  1279.     {
  1280.         static $lnEnd;
  1281.         static $cellAmount;
  1282.         static $determinate;
  1283.  
  1284.         if(!isset($lnEnd)) {
  1285.             $ui =& $this->_UI;
  1286.             $lnEnd = $ui->_getLineEnd();
  1287.             $cellAmount = ($this->getMaximum() - $this->getMinimum()) / $ui->getCellCount();
  1288.         }
  1289.  
  1290.         if (function_exists('ob_get_clean')) {
  1291.             $bar  = ob_get_clean();      // use for PHP 4.3+
  1292.         } else {
  1293.             $bar  = ob_get_contents();   // use for PHP 4.2+
  1294.             ob_end_clean();
  1295.         }
  1296.         $bar .= $lnEnd;
  1297.  
  1298.         $progressId = $this->getIdent().'_';
  1299.  
  1300.         if ($this->isIndeterminate()) {
  1301.             if (isset($determinate)) {
  1302.                 $determinate++;
  1303.                 $progress = $determinate;
  1304.             } else {
  1305.                 $progress = $determinate = 1;
  1306.             }
  1307.         } else {
  1308.             $progress = ($this->getValue() - $this->getMinimum()) / $cellAmount;
  1309.             $determinate = 0;
  1310.     }
  1311.         $bar .= '<script type="text/javascript">self.setprogress("'.$progressId.'",'.((int) $progress).',"'.$this->getString().'",'.$determinate.'); </script>';
  1312.  
  1313.         echo $bar;
  1314.         ob_start();
  1315.     }
  1316.  
  1317.     /**
  1318.      * Hides the progress bar.
  1319.      *
  1320.      * @return     void
  1321.      * @since      1.2.0RC3
  1322.      * @access     public
  1323.      */
  1324.     function hide()
  1325.     {
  1326.         $ui = $this->getUI();
  1327.         $lnEnd = $ui->_getLineEnd();
  1328.         $progressId = $this->getIdent().'_';
  1329.  
  1330.         if (function_exists('ob_get_clean')) {
  1331.             $bar  = ob_get_clean();      // use for PHP 4.3+
  1332.         } else {
  1333.             $bar  = ob_get_contents();   // use for PHP 4.2+
  1334.             ob_end_clean();
  1335.         }
  1336.         $bar .= $lnEnd;
  1337.         $bar .= '<script type="text/javascript">self.hideProgress("'.$progressId.'"); </script>';
  1338.         echo $bar;
  1339.     }
  1340.  
  1341.     /**
  1342.      * Default user callback when none are defined.
  1343.      * Delay execution of progress meter for the given number of milliseconds.
  1344.      *
  1345.      * NOTE: The function {@link http://www.php.net/manual/en/function.usleep.php}
  1346.      *       did not work on Windows systems until PHP 5.0.0
  1347.      *
  1348.      * @return     void
  1349.      * @since      1.2.0RC3
  1350.      * @access     public
  1351.      * @see        getAnimSpeed(), setAnimSpeed(), process()
  1352.      */
  1353.     function sleep()
  1354.     {
  1355.         // convert delay from milliseconds to microseconds
  1356.         $usecs = $this->getAnimSpeed()*1000;
  1357.  
  1358.         if ((substr(PHP_OS, 0, 3) == 'WIN') && (substr(PHP_VERSION,0,1) < '5') ){
  1359.             for ($i=0; $i<$usecs; $i++) { }
  1360.         } else {
  1361.             usleep($usecs);
  1362.     }
  1363.     }
  1364.  
  1365.     /**
  1366.      * Sets the user callback function that execute all actions pending progress
  1367.      *
  1368.      * @param      mixed     $handler       Name of function or a class-method.
  1369.      *
  1370.      * @return     void
  1371.      * @since      1.2.0RC3
  1372.      * @access     public
  1373.      * @throws     HTML_PROGRESS_ERROR_INVALID_CALLBACK
  1374.      * @see        process()
  1375.      */
  1376.     function setProgressHandler($handler)
  1377.     {
  1378.         if (!is_callable($handler)) {
  1379.             return HTML_Progress::raiseError(HTML_PROGRESS_ERROR_INVALID_CALLBACK, 'warning',
  1380.                 array('var' => '$handler',
  1381.                       'element' => 'valid Class-Method/Function',
  1382.                       'was' => 'element',
  1383.                       'paramnum' => 1));
  1384.         }
  1385.         $this->_callback = $handler;
  1386.     }
  1387.  
  1388.     /**
  1389.      * Performs the progress actions
  1390.      *
  1391.      * @return     void
  1392.      * @since      1.2.0RC3
  1393.      * @access     public
  1394.      * @see        sleep()
  1395.      */
  1396.     function process()
  1397.     {
  1398.         if (!$this->_callbackExists($this->_callback)) {
  1399.             // when there is no valid user callback then default is to sleep a bit ...
  1400.             $this->sleep();
  1401.         } else {
  1402.             call_user_func_array($this->_callback, array($this->getValue(), &$this));
  1403.         }
  1404.     }
  1405.  
  1406.     /**
  1407.      * Runs the progress bar (both modes: indeterminate and determinate),
  1408.      * and execute all actions defined in user callback identified by
  1409.      * method setProgressHandler.
  1410.      *
  1411.      * @return     void
  1412.      * @since      1.2.0RC3
  1413.      * @access     public
  1414.      * @see        process(), setProgressHandler()
  1415.      */
  1416.     function run()
  1417.     {
  1418.         do {
  1419.             $this->display();
  1420.             $this->process();
  1421.             if ($this->getPercentComplete() == 1) {
  1422.                 if ($this->isIndeterminate()) {
  1423.                     $this->setValue(0);
  1424.                 } else {
  1425.                     return;
  1426.                 }
  1427.             }
  1428.             $this->incValue();
  1429.         } while(1);
  1430.     }
  1431.  
  1432.     /**
  1433.      * Returns the current identification string.
  1434.      *
  1435.      * @return     string                   current Progress instance's identification string
  1436.      * @since      1.0
  1437.      * @access     public
  1438.      * @see        setIdent()
  1439.      */
  1440.     function getIdent()
  1441.     {
  1442.         return $this->_ident;
  1443.     }
  1444.  
  1445.     /**
  1446.      * Sets this Progress instance's identification string.
  1447.      *
  1448.      * @param      mixed     $ident         (optional) the new identification string.
  1449.      *
  1450.      * @since      1.0
  1451.      * @access     public
  1452.      * @see        getIdent()
  1453.      */
  1454.     function setIdent($ident = null)
  1455.     {
  1456.         if (is_null($ident)) {
  1457.             $this->_ident = 'p_' . substr(md5(microtime()), 0, 6);
  1458.         } else {
  1459.             $this->_ident = $ident;
  1460.     }
  1461.     }
  1462.  
  1463.     /**
  1464.      * Returns an array of all the listeners added to this progress bar.
  1465.      *
  1466.      * @return     array
  1467.      * @since      1.0
  1468.      * @access     public
  1469.      * @see        addListener(), removeListener()
  1470.      */
  1471.     function getListeners()
  1472.     {
  1473.         return $this->_listeners;
  1474.     }
  1475.  
  1476.     /**
  1477.      * Adds a HTML_Progress_Observer instance to the list of observers
  1478.      * that are listening for messages emitted by this HTML_Progress instance.
  1479.      *
  1480.      * @param      object    $observer      The HTML_Progress_Observer instance
  1481.      *                                      to attach as a listener.
  1482.      *
  1483.      * @return     boolean                  True if the observer is successfully attached.
  1484.      * @since      1.0
  1485.      * @access     public
  1486.      * @see        getListeners(), removeListener()
  1487.      */
  1488.     function addListener($observer)
  1489.     {
  1490.         if (!is_a($observer, 'HTML_Progress_Observer') &&
  1491.             !is_a($observer, 'HTML_Progress_Monitor')) {
  1492.             return false;
  1493.         }
  1494.         $this->_listeners[$observer->_id] = &$observer;
  1495.         return true;
  1496.     }
  1497.  
  1498.     /**
  1499.      * Removes a HTML_Progress_Observer instance from the list of observers.
  1500.      *
  1501.      * @param      object    $observer      The HTML_Progress_Observer instance
  1502.      *                                      to detach from the list of listeners.
  1503.      *
  1504.      * @return     boolean                  True if the observer is successfully detached.
  1505.      * @since      1.0
  1506.      * @access     public
  1507.      * @see        getListeners(), addListener()
  1508.      */
  1509.     function removeListener($observer)
  1510.     {
  1511.         if ((!is_a($observer, 'HTML_Progress_Observer') &&
  1512.              !is_a($observer, 'HTML_Progress_Monitor')
  1513.              ) ||
  1514.             (!isset($this->_listeners[$observer->_id]))  ) {
  1515.  
  1516.             return false;
  1517.         }
  1518.         unset($this->_listeners[$observer->_id]);
  1519.         return true;
  1520.     }
  1521.  
  1522.     /**
  1523.      * Notifies all listeners that have registered interest in $event message.
  1524.      *
  1525.      * @param      mixed     $event         A hash describing the progress event.
  1526.      *
  1527.      * @since      1.0
  1528.      * @access     private
  1529.      * @see        setMinimum(), setMaximum(), setValue(), incValue()
  1530.      */
  1531.     function _announce($event)
  1532.     {
  1533.         foreach ($this->_listeners as $id => $listener) {
  1534.             $this->_listeners[$id]->notify($event);
  1535.         }
  1536.     }
  1537.  
  1538.     /**
  1539.      * Returns a horizontal progress bar structure as HTML.
  1540.      *
  1541.      * @return     string                   Horizontal HTML Progress bar
  1542.      * @since      1.0
  1543.      * @access     private
  1544.      */
  1545.     function _getProgressHbar_toHtml()
  1546.     {
  1547.         $ui =& $this->_UI;
  1548.         $tabs = $ui->_getTabs();
  1549.         $tab = $ui->_getTab();
  1550.         $lnEnd = $ui->_getLineEnd();
  1551.         $way_natural = ($ui->getFillWay() == 'natural');
  1552.         $cellAttr = $ui->getCellAttributes();
  1553.         $cellCount = $ui->getCellCount();
  1554.  
  1555.         $progressId = $this->getIdent().'_';
  1556.         $progressHtml = "";
  1557.  
  1558.         if ($way_natural) {
  1559.             // inactive cells first
  1560.             $pos = $cellAttr['spacing'];
  1561.             for ($i=0; $i<$cellCount; $i++) {
  1562.                 $progressHtml .= $tabs . $tab . $tab;
  1563.                 $progressHtml .= "<div id=\"". $progressId . sprintf($cellAttr['id'],$i) ."I\"";
  1564.                 $progressHtml .= " class=\"".$cellAttr['class']."I\"";
  1565.                 $progressHtml .= " style=\"position:absolute;top:".$cellAttr['spacing']."px;left:".$pos."px;\"";
  1566.                 $progressHtml .= "> </div>" . $lnEnd;
  1567.                 $pos += ($cellAttr['width'] + $cellAttr['spacing']);
  1568.             }
  1569.             // then active cells
  1570.             $pos = $cellAttr['spacing'];
  1571.             for ($i=0; $i<$cellCount; $i++) {
  1572.                 $progressHtml .= $tabs . $tab . $tab;
  1573.                 $progressHtml .= "<div id=\"". $progressId . sprintf($cellAttr['id'],$i) ."A\"";
  1574.                 $progressHtml .= " class=\"".$cellAttr['class']."A\"";
  1575.                 $progressHtml .= " style=\"position:absolute;top:".$cellAttr['spacing']."px;left:".$pos."px;";
  1576.                 if (isset($cellAttr[$i])) {
  1577.                     $progressHtml .= "color:".$cellAttr[$i]['color'].";\"";
  1578.                 } else {
  1579.                     $progressHtml .= "\"";
  1580.                 }
  1581.                 $progressHtml .= "> </div>" . $lnEnd;
  1582.                 $pos += ($cellAttr['width'] + $cellAttr['spacing']);
  1583.             }
  1584.         } else {
  1585.             // inactive cells first
  1586.             $pos = $cellAttr['spacing'];
  1587.             for ($i=$cellCount-1; $i>=0; $i--) {
  1588.                 $progressHtml .= $tabs . $tab . $tab;
  1589.                 $progressHtml .= "<div id=\"". $progressId . sprintf($cellAttr['id'],$i) ."I\"";
  1590.                 $progressHtml .= " class=\"".$cellAttr['class']."I\"";
  1591.                 $progressHtml .= " style=\"position:absolute;top:".$cellAttr['spacing']."px;left:".$pos."px;\"";
  1592.                 $progressHtml .= "> </div>" . $lnEnd;
  1593.                 $pos += ($cellAttr['width'] + $cellAttr['spacing']);
  1594.             }
  1595.             // then active cells
  1596.             $pos = $cellAttr['spacing'];
  1597.             for ($i=$cellCount-1; $i>=0; $i--) {
  1598.                 $progressHtml .= $tabs . $tab . $tab;
  1599.                 $progressHtml .= "<div id=\"". $progressId . sprintf($cellAttr['id'],$i) ."A\"";
  1600.                 $progressHtml .= " class=\"".$cellAttr['class']."A\"";
  1601.                 $progressHtml .= " style=\"position:absolute;top:".$cellAttr['spacing']."px;left:".$pos."px;";
  1602.                 if (isset($cellAttr[$i])) {
  1603.                     $progressHtml .= "color:".$cellAttr[$i]['color'].";\"";
  1604.                 } else {
  1605.                     $progressHtml .= "\"";
  1606.                 }
  1607.                 $progressHtml .= "> </div>" . $lnEnd;
  1608.                 $pos += ($cellAttr['width'] + $cellAttr['spacing']);
  1609.             }
  1610.         }
  1611.         return $progressHtml;
  1612.     }
  1613.  
  1614.     /**
  1615.      * Returns a vertical progress bar structure as HTML.
  1616.      *
  1617.      * @return     string                   Vertical HTML Progress bar
  1618.      * @since      1.0
  1619.      * @access     private
  1620.      */
  1621.     function _getProgressVbar_toHtml()
  1622.     {
  1623.         $ui =& $this->_UI;
  1624.         $tabs = $ui->_getTabs();
  1625.         $tab = $ui->_getTab();
  1626.         $lnEnd = $ui->_getLineEnd();
  1627.         $way_natural = ($ui->getFillWay() == 'natural');
  1628.         $cellAttr = $ui->getCellAttributes();
  1629.         $cellCount = $ui->getCellCount();
  1630.  
  1631.         $progressId = $this->getIdent().'_';
  1632.         $progressHtml = "";
  1633.  
  1634.         if ($way_natural) {
  1635.             // inactive cells first
  1636.             $pos = $cellAttr['spacing'];
  1637.             for ($i=$cellCount-1; $i>=0; $i--) {
  1638.                 $progressHtml .= $tabs . $tab . $tab;
  1639.                 $progressHtml .= "<div id=\"". $progressId . sprintf($cellAttr['id'],$i) ."I\"";
  1640.                 $progressHtml .= " class=\"".$cellAttr['class']."I\"";
  1641.                 $progressHtml .= " style=\"position:absolute;left:".$cellAttr['spacing']."px;top:".$pos."px;\"";
  1642.                 $progressHtml .= "> </div>" . $lnEnd;
  1643.                 $pos += ($cellAttr['height'] + $cellAttr['spacing']);
  1644.             }
  1645.             // then active cells
  1646.             $pos = $cellAttr['spacing'];
  1647.             for ($i=$cellCount-1; $i>=0; $i--) {
  1648.                 $progressHtml .= $tabs . $tab . $tab;
  1649.                 $progressHtml .= "<div id=\"". $progressId . sprintf($cellAttr['id'],$i) ."A\"";
  1650.                 $progressHtml .= " class=\"".$cellAttr['class']."A\"";
  1651.                 $progressHtml .= " style=\"position:absolute;left:".$cellAttr['spacing']."px;top:".$pos."px;";
  1652.                 if (isset($cellAttr[$i])) {
  1653.                     $progressHtml .= "color:".$cellAttr[$i]['color'].";\"";
  1654.                 } else {
  1655.                     $progressHtml .= "\"";
  1656.                 }
  1657.                 $progressHtml .= "> </div>" . $lnEnd;
  1658.                 $pos += ($cellAttr['height'] + $cellAttr['spacing']);
  1659.             }
  1660.         } else {
  1661.             // inactive cells first
  1662.             $pos = $cellAttr['spacing'];
  1663.             for ($i=0; $i<$cellCount; $i++) {
  1664.                 $progressHtml .= $tabs . $tab . $tab;
  1665.                 $progressHtml .= "<div id=\"". $progressId . sprintf($cellAttr['id'],$i) ."I\"";
  1666.                 $progressHtml .= " class=\"".$cellAttr['class']."I\"";
  1667.                 $progressHtml .= " style=\"position:absolute;left:".$cellAttr['spacing']."px;top:".$pos."px;\"";
  1668.                 $progressHtml .= "> </div>" . $lnEnd;
  1669.                 $pos += ($cellAttr['height'] + $cellAttr['spacing']);
  1670.             }
  1671.             // then active cells
  1672.             $pos = $cellAttr['spacing'];
  1673.             for ($i=0; $i<$cellCount; $i++) {
  1674.                 $progressHtml .= $tabs . $tab . $tab;
  1675.                 $progressHtml .= "<div id=\"". $progressId . sprintf($cellAttr['id'],$i) ."A\"";
  1676.                 $progressHtml .= " class=\"".$cellAttr['class']."A\"";
  1677.                 $progressHtml .= " style=\"position:absolute;left:".$cellAttr['spacing']."px;top:".$pos."px;";
  1678.                 if (isset($cellAttr[$i])) {
  1679.                     $progressHtml .= "color:".$cellAttr[$i]['color'].";\"";
  1680.                 } else {
  1681.                     $progressHtml .= "\"";
  1682.                 }
  1683.                 $progressHtml .= "> </div>" . $lnEnd;
  1684.                 $pos += ($cellAttr['height'] + $cellAttr['spacing']);
  1685.             }
  1686.         }
  1687.         return $progressHtml;
  1688.     }
  1689.  
  1690.     /**
  1691.      * Returns a polygonal progress structure as HTML.
  1692.      *
  1693.      * @return     string                   Polygonal HTML Progress
  1694.      * @since      1.2.0RC1
  1695.      * @access     private
  1696.      */
  1697.     function _getProgressPolygonal_toHtml()
  1698.     {
  1699.         $ui =& $this->_UI;
  1700.         $tabs = $ui->_getTabs();
  1701.         $tab = $ui->_getTab();
  1702.         $lnEnd = $ui->_getLineEnd();
  1703.         $way_natural = ($ui->getFillWay() == 'natural');
  1704.         $cellAttr = $ui->getCellAttributes();
  1705.         $cellCount = $ui->getCellCount();
  1706.         $coord = $ui->_coordinates;
  1707.  
  1708.         $progressId = $this->getIdent().'_';
  1709.         $progressHtml = "";
  1710.  
  1711.         if ($way_natural) {
  1712.             // inactive cells first
  1713.             for ($i=0; $i<$cellCount; $i++) {
  1714.                 $top  = $coord[$i][0] * $cellAttr['width'];
  1715.                 $left = $coord[$i][1] * $cellAttr['height'];
  1716.                 $progressHtml .= $tabs . $tab . $tab;
  1717.                 $progressHtml .= "<div id=\"". $progressId . sprintf($cellAttr['id'],$i) ."I\"";
  1718.                 $progressHtml .= " class=\"".$cellAttr['class']."I\"";
  1719.                 $progressHtml .= " style=\"position:absolute;top:".$top."px;left:".$left."px;\"";
  1720.                 $progressHtml .= "> </div>" . $lnEnd;
  1721.             }
  1722.             // then active cells
  1723.             for ($i=0; $i<$cellCount; $i++) {
  1724.                 $top  = $coord[$i][0] * $cellAttr['width'];
  1725.                 $left = $coord[$i][1] * $cellAttr['height'];
  1726.                 $progressHtml .= $tabs . $tab . $tab;
  1727.                 $progressHtml .= "<div id=\"". $progressId . sprintf($cellAttr['id'],$i) ."A\"";
  1728.                 $progressHtml .= " class=\"".$cellAttr['class']."A\"";
  1729.                 $progressHtml .= " style=\"position:absolute;top:".$top."px;left:".$left."px;\"";
  1730.                 if (isset($cellAttr[$i])) {
  1731.                     $progressHtml .= "color:".$cellAttr[$i]['color'].";\"";
  1732.                 } else {
  1733.                     $progressHtml .= "\"";
  1734.                 }
  1735.                 $progressHtml .= "> </div>" . $lnEnd;
  1736.             }
  1737.         } else {
  1738.             $c = count($coord) - 1;
  1739.             // inactive cells first
  1740.             for ($i=0; $i<$cellCount; $i++) {
  1741.                 $top  = $coord[$c-$i][0] * $cellAttr['width'];
  1742.                 $left = $coord[$c-$i][1] * $cellAttr['height'];
  1743.                 $progressHtml .= $tabs . $tab . $tab;
  1744.                 $progressHtml .= "<div id=\"". $progressId . sprintf($cellAttr['id'],$i) ."I\"";
  1745.                 $progressHtml .= " class=\"".$cellAttr['class']."I\"";
  1746.                 $progressHtml .= " style=\"position:absolute;top:".$top."px;left:".$left."px;\"";
  1747.                 $progressHtml .= "> </div>" . $lnEnd;
  1748.             }
  1749.             // then active cells
  1750.             for ($i=0; $i<$cellCount; $i++) {
  1751.                 $top  = $coord[$c-$i][0] * $cellAttr['width'];
  1752.                 $left = $coord[$c-$i][1] * $cellAttr['height'];
  1753.                 $progressHtml .= $tabs . $tab . $tab;
  1754.                 $progressHtml .= "<div id=\"". $progressId . sprintf($cellAttr['id'],$i) ."A\"";
  1755.                 $progressHtml .= " class=\"".$cellAttr['class']."A\"";
  1756.                 $progressHtml .= " style=\"position:absolute;top:".$top."px;left:".$left."px;\"";
  1757.                 if (isset($cellAttr[$i])) {
  1758.                     $progressHtml .= "color:".$cellAttr[$i]['color'].";\"";
  1759.                 } else {
  1760.                     $progressHtml .= "\"";
  1761.                 }
  1762.                 $progressHtml .= "> </div>" . $lnEnd;
  1763.             }
  1764.         }
  1765.         return $progressHtml;
  1766.     }
  1767.  
  1768.     /**
  1769.      * Returns a circle progress structure as HTML.
  1770.      *
  1771.      * @return     string                   Circle HTML Progress
  1772.      * @since      1.2.0RC1
  1773.      * @access     private
  1774.      */
  1775.     function _getProgressCircle_toHtml()
  1776.     {
  1777.         $ui =& $this->_UI;
  1778.         $tabs = $ui->_getTabs();
  1779.         $tab = $ui->_getTab();
  1780.         $lnEnd = $ui->_getLineEnd();
  1781.         $way_natural = ($ui->getFillWay() == 'natural');
  1782.         $cellAttr = $ui->getCellAttributes();
  1783.         $cellCount = $ui->getCellCount();
  1784.  
  1785.         $progressId = $this->getIdent().'_';
  1786.         $progressHtml = "";
  1787.  
  1788.         if ($way_natural) {
  1789.             // inactive cells first
  1790.             for ($i=0; $i<$cellCount; $i++) {
  1791.                 $progressHtml .= $tabs . $tab . $tab;
  1792.                 $progressHtml .= "<div id=\"". $progressId . sprintf($cellAttr['id'],$i) ."I\"";
  1793.                 $progressHtml .= " class=\"".$cellAttr['class']."I\"";
  1794.                 $progressHtml .= " style=\"position:absolute;top:0;left:0;\"";
  1795.                 $progressHtml .= "> </div>" . $lnEnd;
  1796.             }
  1797.             // then active cells
  1798.             for ($i=0; $i<$cellCount; $i++) {
  1799.                 $progressHtml .= $tabs . $tab . $tab;
  1800.                 $progressHtml .= "<div id=\"". $progressId . sprintf($cellAttr['id'],$i) ."A\"";
  1801.                 $progressHtml .= " class=\"".$cellAttr['class']."A\"";
  1802.                 $progressHtml .= " style=\"position:absolute;top:0;left:0;\"";
  1803.                 $progressHtml .= "><img src=\"".$cellAttr[$i+1]['background-image']."\" border=\"0\" /></div>" . $lnEnd;
  1804.             }
  1805.         } else {
  1806.             // inactive cells first
  1807.             for ($i=0; $i<$cellCount; $i++) {
  1808.                 $progressHtml .= $tabs . $tab . $tab;
  1809.                 $progressHtml .= "<div id=\"". $progressId . sprintf($cellAttr['id'],$i) ."I\"";
  1810.                 $progressHtml .= " class=\"".$cellAttr['class']."I\"";
  1811.                 $progressHtml .= " style=\"position:absolute;top:0;left:0;\"";
  1812.                 $progressHtml .= "> </div>" . $lnEnd;
  1813.             }
  1814.             // then active cells
  1815.             for ($i=0; $i<$cellCount; $i++) {
  1816.                 $progressHtml .= $tabs . $tab . $tab;
  1817.                 $progressHtml .= "<div id=\"". $progressId . sprintf($cellAttr['id'],$i) ."A\"";
  1818.                 $progressHtml .= " class=\"".$cellAttr['class']."A\"";
  1819.                 $progressHtml .= " style=\"position:absolute;top:0;left:0;\"";
  1820.                 $progressHtml .= "><img src=\"".$cellAttr[$i+1]['background-image']."\" border=\"0\" /></div>" . $lnEnd;
  1821.             }
  1822.         }
  1823.         return $progressHtml;
  1824.     }
  1825.  
  1826.     /**
  1827.      * Checks for callback function existance
  1828.      *
  1829.      * @param      mixed     $callback      a callback, like one used by call_user_func()
  1830.      *
  1831.      * @return     boolean
  1832.      * @since      1.2.0RC3
  1833.      * @access     private
  1834.      */
  1835.     function _callbackExists($callback)
  1836.     {
  1837.         if (is_string($callback)) {
  1838.             return function_exists($callback);
  1839.         } elseif (is_array($callback) && is_object($callback[0])) {
  1840.             return method_exists($callback[0], $callback[1]);
  1841.         } else {
  1842.             return false;
  1843.         }
  1844.     }
  1845.  
  1846.     /**
  1847.      * Initialize Error Handler
  1848.      *
  1849.      * Parameter '$prefs' contains a hash of options to define the error handler.
  1850.      * You may find :
  1851.      *  'message_callback'  A callback to generate message body.
  1852.      *                      Default is:  HTML_Progress::_msgCallback()
  1853.      *  'context_callback'  A callback to generate context of error.
  1854.      *                      Default is:  HTML_Progress::_getBacktrace()
  1855.      *  'push_callback'     A callback to determine whether to allow an error
  1856.      *                      to be pushed or logged.
  1857.      *                      Default is:  HTML_Progress::_handleError()
  1858.      *  'error_handler'     A callback to manage all error raised.
  1859.      *                      Default is:  HTML_Progress::_errorHandler()
  1860.      *  'handler'           Hash of params to configure all handlers (display, file, mail ...)
  1861.      *                      There are only a display handler by default with options below:
  1862.      *  <code>
  1863.      *  array('display' => array('conf' => $options));
  1864.      *  // where $options are:
  1865.      *  $options = array(
  1866.      *      'lineFormat' => '<b>%1$s</b>: %2$s %3$s',
  1867.      *      'contextFormat' => ' in <b>%3$s</b> (file <b>%1$s</b> at line <b>%2$s</b>)'
  1868.      *  );
  1869.      *  </code>
  1870.      *
  1871.      * @param      array     $prefs         hash of params to configure error handler
  1872.      *
  1873.      * @return     void
  1874.      * @since      1.2.0
  1875.      * @access     private
  1876.      * @static
  1877.      */
  1878.     function _initErrorHandler($prefs = array())
  1879.     {
  1880.         // error message mapping callback
  1881.         if (isset($prefs['message_callback']) && is_callable($prefs['message_callback'])) {
  1882.             $GLOBALS['_HTML_PROGRESS_CALLBACK_MESSAGE'] = $prefs['message_callback'];
  1883.         } else {
  1884.             $GLOBALS['_HTML_PROGRESS_CALLBACK_MESSAGE'] = array('HTML_Progress', '_msgCallback');
  1885.         }
  1886.  
  1887.         // error context mapping callback
  1888.         if (isset($prefs['context_callback']) && is_callable($prefs['context_callback'])) {
  1889.             $GLOBALS['_HTML_PROGRESS_CALLBACK_CONTEXT'] = $prefs['context_callback'];
  1890.         } else {
  1891.             $GLOBALS['_HTML_PROGRESS_CALLBACK_CONTEXT'] = array('HTML_Progress', '_getBacktrace');
  1892.         }
  1893.  
  1894.         // determine whether to allow an error to be pushed or logged
  1895.         if (isset($prefs['push_callback']) && is_callable($prefs['push_callback'])) {
  1896.             $GLOBALS['_HTML_PROGRESS_CALLBACK_PUSH'] = $prefs['push_callback'];
  1897.         } else {
  1898.             $GLOBALS['_HTML_PROGRESS_CALLBACK_PUSH'] = array('HTML_Progress', '_handleError');
  1899.         }
  1900.  
  1901.         // default error handler will use PEAR_Error
  1902.         if (isset($prefs['error_handler']) && is_callable($prefs['error_handler'])) {
  1903.             $GLOBALS['_HTML_PROGRESS_CALLBACK_ERRORHANDLER'] = $prefs['error_handler'];
  1904.         } else {
  1905.             $GLOBALS['_HTML_PROGRESS_CALLBACK_ERRORHANDLER'] = array('HTML_Progress', '_errorHandler');
  1906.         }
  1907.  
  1908.         // only a display handler is set by default with specific settings
  1909.         $conf = array('lineFormat' => '<b>%1$s</b>: %2$s %3$s',
  1910.                       'contextFormat' => ' in <b>%3$s</b> (file <b>%1$s</b> at line <b>%2$s</b>)'
  1911.                       );
  1912.  
  1913.         $optionsHandler['display'] = array('conf' => $conf);
  1914.  
  1915.         if (isset($prefs['handler'])) {
  1916.             $optionsHandler = array_merge($optionsHandler, $prefs['handler']);
  1917.         }
  1918.         $GLOBALS['_HTML_PROGRESS_ERRORHANDLER_OPTIONS'] = $optionsHandler;
  1919.     }
  1920.  
  1921.     /**
  1922.      * Default callback to generate error messages for any instance
  1923.      *
  1924.      * @param      array     $err           current error structure with context info
  1925.      *
  1926.      * @return     string
  1927.      * @since      1.2.0RC1
  1928.      * @access     private
  1929.      * @static
  1930.      */
  1931.     function _msgCallback($err)
  1932.     {
  1933.         $messages = HTML_Progress::_getErrorMessage();
  1934.         $mainmsg = $messages[$err['code']];
  1935.  
  1936.         if (count($err['params'])) {
  1937.             foreach ($err['params'] as $name => $val) {
  1938.                 if (is_array($val)) {
  1939.                     $val = implode(', ', $val);
  1940.                 }
  1941.                 $mainmsg = str_replace('%' . $name . '%', $val,  $mainmsg);
  1942.             }
  1943.         }
  1944.         return $mainmsg;
  1945.     }
  1946.  
  1947.     /**
  1948.      * Standard file/line number/function/class context callback
  1949.      *
  1950.      * @return     false|array
  1951.      * @since      1.2.0
  1952.      * @access     private
  1953.      * @static
  1954.      */
  1955.     function _getBacktrace()
  1956.     {
  1957.         if (function_exists('debug_backtrace')) {
  1958.             $backtrace = debug_backtrace();     // PHP 4.3+
  1959.             $backtrace = $backtrace[count($backtrace)-1];
  1960.         } else {
  1961.             $backtrace = false;                 // PHP 4.1.x, 4.2.x (no context info available)
  1962.         }
  1963.         return $backtrace;
  1964.     }
  1965.  
  1966.     /**
  1967.      * Standard callback, this will be called every time an error
  1968.      * is pushed onto the stack.  The return value will be used to determine
  1969.      * whether to allow an error to be pushed or logged.
  1970.      * Dies if the error is an exception (and would have died anyway)
  1971.      *
  1972.      * @param      array     $err           current error structure with context info
  1973.      *
  1974.      * @return     null|HTML_PROGRESS_ERRORSTACK_* constant
  1975.      * @since      1.2.0RC2
  1976.      * @access     private
  1977.      * @static
  1978.      * @see        HTML_PROGRESS_ERRORSTACK_PUSHANDLOG, HTML_PROGRESS_ERRORSTACK_PUSH,
  1979.      *             HTML_PROGRESS_ERRORSTACK_LOG, HTML_PROGRESS_ERRORSTACK_IGNORE,
  1980.      *             HTML_PROGRESS_ERRORSTACK_LOGANDDIE
  1981.      *
  1982.      */
  1983.     function _handleError($err)
  1984.     {
  1985.         if ($err['level'] == 'exception') {
  1986.             return HTML_PROGRESS_ERRORSTACK_LOGANDDIE;
  1987.         }
  1988.     }
  1989.  
  1990.     /**
  1991.      * Standard error handler that will use PEAR_Error object
  1992.      *
  1993.      * To improve performances, the PEAR.php file is included dynamically.
  1994.      * The file is so included only when an error is triggered. So, in most
  1995.      * cases, the file isn't included and perfs are much better.
  1996.      *
  1997.      * @param      array     $err           current error structure with context info
  1998.      *
  1999.      * @return     PEAR_Error
  2000.      * @since      1.2.0
  2001.      * @access     private
  2002.      * @static
  2003.      */
  2004.     function _errorHandler($err)
  2005.     {
  2006.         include_once 'PEAR.php';
  2007.         $e = PEAR::raiseError($err['message'], $err['code'], PEAR_ERROR_RETURN, E_USER_ERROR,
  2008.                               $err['context']);
  2009.  
  2010.         if (isset($err['context'])) {
  2011.             $file  = $err['context']['file'];
  2012.             $line  = $err['context']['line'];
  2013.             $func  = $err['context']['class'];
  2014.             $func .= $err['context']['type'];
  2015.             $func .= $err['context']['function'];
  2016.         }
  2017.  
  2018.         $display_errors = ini_get('display_errors');
  2019.         $log_errors = ini_get('log_errors');
  2020.  
  2021.         $display = $GLOBALS['_HTML_PROGRESS_ERRORHANDLER_OPTIONS']['display'];
  2022.  
  2023.         if ($display_errors) {
  2024.             $lineFormat = $display['conf']['lineFormat'];
  2025.             $contextFormat = $display['conf']['contextFormat'];
  2026.  
  2027.             $context = sprintf($contextFormat, $file, $line, $func);
  2028.  
  2029.             printf($lineFormat."<br />\n", ucfirst($err['level']), $err['message'], $context);
  2030.         }
  2031.  
  2032.         if ($log_errors) {
  2033.             if (isset($GLOBALS['_HTML_PROGRESS_ERRORHANDLER_OPTIONS']['error_log'])) {
  2034.                 $error_log = $GLOBALS['_HTML_PROGRESS_ERRORHANDLER_OPTIONS']['error_log'];
  2035.                 $message_type = $error_log['name'];
  2036.                 $destination = '';
  2037.                 $extra_headers = '';
  2038.                 $send = true;
  2039.  
  2040.                 switch ($message_type) {
  2041.                     case HTML_PROGRESS_LOG_TYPE_SYSTEM:
  2042.                         break;
  2043.                     case HTML_PROGRESS_LOG_TYPE_MAIL:
  2044.                         $destination = $error_log['conf']['destination'];
  2045.                         $extra_headers = $error_log['conf']['extra_headers'];
  2046.                         break;
  2047.                     case HTML_PROGRESS_LOG_TYPE_FILE:
  2048.                         $destination = $error_log['conf']['destination'];
  2049.                         break;
  2050.                     default:
  2051.                         $send = false;
  2052.                 }
  2053.                 if ($send) {
  2054.                     /**
  2055.                      * String containing the format of a log line.
  2056.                      * Position arguments are:
  2057.                      *  $1 -> timestamp
  2058.                      *  $2 -> ident
  2059.                      *  $3 -> level
  2060.                      *  $4 -> message
  2061.                      *  $5 -> context
  2062.                      */
  2063.                     if (isset($error_log['conf']['lineFormat'])) {
  2064.                         $lineFormat = $error_log['conf']['lineFormat'];
  2065.                     } else {
  2066.                         $lineFormat = '%1$s %2$s [%3$s] %4$s %5$s';
  2067.                     }
  2068.  
  2069.                     /**
  2070.                      * String containing the timestamp format
  2071.                      */
  2072.                     if (isset($error_log['conf']['timeFormat'])) {
  2073.                         $timeFormat = $error_log['conf']['timeFormat'];
  2074.                     } else {
  2075.                         $timeFormat = '%b %d %H:%M:%S';
  2076.                     }
  2077.  
  2078.                     /**
  2079.                      * String containing the error execution context format
  2080.                      */
  2081.                     if (isset($error_log['conf']['contextFormat'])) {
  2082.                         $contextFormat = $error_log['conf']['contextFormat'];
  2083.                     } else {
  2084.                         $contextFormat = strip_tags($display['conf']['contextFormat']);
  2085.                     }
  2086.  
  2087.                     /**
  2088.                      * String containing the end-on-line character sequence
  2089.                      */
  2090.                     if (isset($error_log['conf']['eol'])) {
  2091.                         $eol = $error_log['conf']['eol'];
  2092.                     } else {
  2093.                         $eol = "\n";
  2094.                     }
  2095.  
  2096.                     $context = sprintf($contextFormat, $file, $line, $func);
  2097.                     $message = sprintf($lineFormat,
  2098.                                        strftime($timeFormat, $err['time']),
  2099.                                        $error_log['ident'],
  2100.                                        $err['level'],
  2101.                                        $err['message'],
  2102.                                        $context);
  2103.  
  2104.                     error_log($message.$eol, $message_type, $destination, $extra_headers);
  2105.                 }
  2106.             }
  2107.         }
  2108.         return $e;
  2109.     }
  2110.  
  2111.     /**
  2112.      * Error Message Template array
  2113.      *
  2114.      * @return     string
  2115.      * @since      1.0
  2116.      * @access     private
  2117.      */
  2118.     function _getErrorMessage()
  2119.     {
  2120.         $messages = array(
  2121.             HTML_PROGRESS_ERROR_INVALID_INPUT =>
  2122.                 'invalid input, parameter #%paramnum% '
  2123.                     . '"%var%" was expecting '
  2124.                     . '"%expected%", instead got "%was%"',
  2125.             HTML_PROGRESS_ERROR_INVALID_CALLBACK =>
  2126.                 'invalid callback, parameter #%paramnum% '
  2127.                     . '"%var%" expecting %element%,'
  2128.                     . ' instead got "%was%" does not exists',
  2129.             HTML_PROGRESS_DEPRECATED =>
  2130.                 'method is deprecated '
  2131.                     . 'use %newmethod% instead of %oldmethod%'
  2132.  
  2133.         );
  2134.         return $messages;
  2135.     }
  2136.  
  2137.     /**
  2138.      * Add an error to the stack
  2139.      *
  2140.      * @param      integer   $code       Error code.
  2141.      * @param      string    $level      The error level of the message.
  2142.      * @param      array     $params     Associative array of error parameters
  2143.      *
  2144.      * @return     NULL|PEAR_Error       PEAR_Error instance,
  2145.      *                                   with context info if PHP 4.3.0+
  2146.      * @since      1.2.0RC1
  2147.      * @access     public
  2148.      * @static
  2149.      * @see        hasErrors(), getError()
  2150.      */
  2151.     function raiseError($code, $level, $params)
  2152.     {
  2153.         // obey at protocol
  2154.         if (error_reporting() == 0) {
  2155.             return;
  2156.         }
  2157.  
  2158.         // grab error context
  2159.         $context = call_user_func($GLOBALS['_HTML_PROGRESS_CALLBACK_CONTEXT']);
  2160.  
  2161.         // save error
  2162.         $time = explode(' ', microtime());
  2163.         $time = $time[1] + $time[0];
  2164.         $err = array(
  2165.                 'code' => $code,
  2166.                 'params' => $params,
  2167.                 'package' => 'HTML_Progress',
  2168.                 'level' => $level,
  2169.                 'time' => $time,
  2170.                 'context' => $context
  2171.                );
  2172.  
  2173.         // set up the error message, if necessary
  2174.         $err['message'] = call_user_func($GLOBALS['_HTML_PROGRESS_CALLBACK_MESSAGE'], $err);
  2175.  
  2176.         $push = $log = true;
  2177.         $die = false;
  2178.         $action = call_user_func($GLOBALS['_HTML_PROGRESS_CALLBACK_PUSH'], $err);
  2179.  
  2180.         switch($action){
  2181.             case HTML_PROGRESS_ERRORSTACK_IGNORE:
  2182.                 $push = $log = false;
  2183.                 break;
  2184.             case HTML_PROGRESS_ERRORSTACK_PUSH:
  2185.                 $log = false;
  2186.                 break;
  2187.             case HTML_PROGRESS_ERRORSTACK_LOG:
  2188.                 $push = false;
  2189.             break;
  2190.             case HTML_PROGRESS_ERRORSTACK_LOGANDDIE:
  2191.                 $push = false;
  2192.                 $die = true;
  2193.             break;
  2194.             // anything else returned has the same effect as pushandlog
  2195.         }
  2196.  
  2197.         $e = false;
  2198.         if ($push) {
  2199.             array_unshift($GLOBALS['_HTML_PROGRESS_ERRORSTACK'], $err);
  2200.         }
  2201.         if ($log) {
  2202.             // default callback returns a PEAR_Error object
  2203.             $e = call_user_func($GLOBALS['_HTML_PROGRESS_CALLBACK_ERRORHANDLER'], $err);
  2204.         }
  2205.         if ($die) {
  2206.             die();
  2207.         }
  2208.         return $e;
  2209.     }
  2210.  
  2211.     /**
  2212.      * Determine whether there are errors into the HTML_Progress stack
  2213.      *
  2214.      * @return     integer
  2215.      * @since      1.2.0RC3
  2216.      * @access     public
  2217.      * @static
  2218.      * @see        getError(), raiseError()
  2219.      */
  2220.     function hasErrors()
  2221.     {
  2222.         return count($GLOBALS['_HTML_PROGRESS_ERRORSTACK']);
  2223.     }
  2224.  
  2225.     /**
  2226.      * Pop an error off of the HTML_Progress stack
  2227.      *
  2228.      * @return     false|array
  2229.      * @since      1.2.0RC3
  2230.      * @access     public
  2231.      * @static
  2232.      * @see        hasErrors(), raiseError()
  2233.      */
  2234.     function getError()
  2235.     {
  2236.         return @array_shift($GLOBALS['_HTML_PROGRESS_ERRORSTACK']);
  2237.     }
  2238. }
  2239. ?>